﻿using EFCore.Extensions;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using XfTechOAWeb.Data.Base;
using XfTechOAWeb.Dtos.Departments;

namespace XfTechOAWeb.EFCore.Base
{
    /// <summary>
    /// Ef泛型仓储基类
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class EfBaseRepository<T> : IRepository<T> where T : class
    {
        //注入上下文服务
        //protected SqlServerDbContext _db;
        //protected MySqlDbContext _db;
        protected DbContext _db;

        public EfBaseRepository(DbContext db)
        {
            //_db = DbContextFactory.CreateDbContext(); //用工厂创建对象
            _db = db;
        }

        private DbSet<T> _entity; //字段
        private DbSet<T> Entity   //对上面的字段封装成了属性
        {
            get
            {  //只返回一个DbSet实例
                if (_entity == null)
                {
                    _entity = _db.Set<T>();
                }
                return _entity;
            }
        }

        #region 实现接口方法
        /// <summary>
        /// 返回可查询对象
        /// </summary>
        public IQueryable<T> Table
        {
            get
            {
                return Entity.AsQueryable();
            }
        }

        /// <summary>
        /// 根据主键获取对象
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public T GetById(object id)
        {
            if (id == null) throw new ArgumentNullException();

            return _db.Set<T>().Find(id);
        }

        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="model"></param>
        public void Insert(T model)
        {
            if (model == null) throw new ArgumentNullException();

            Entity.Add(model); //添加
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="id"></param>
        public void Remove(object id)
        {
            //如果查到不为空，则删除
            T obj = GetById(id);
            if (obj != null)
                Entity.Remove(obj);
        }

        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="model"></param>
        public void Update(T model)
        {
            Entity.Update(model);
        }

        /// <summary>
        /// 保存更改
        /// </summary>
        /// <returns></returns>
        public int SaveChanges()
        {
            return _db.SaveChanges();
        }

        /// <summary>
        /// 保存更改异步方法
        /// </summary>
        /// <returns></returns>
        public async Task<int> SaveChangesAsync()
        {
            return await _db.SaveChangesAsync();
        }

        /// <summary>
        /// 执行sql语句
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        public IEnumerable<dynamic> QueryFromSql(string sql, params DbParameter[] parameters)
        {
            return _db.ExecuteSqlQuery(sql, CommandType.Text, parameters);
        }

        /// <summary>
        /// 执行存储过程
        /// </summary>
        /// <param name="procName"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        public IEnumerable<dynamic> QueryFromProc(string procName, params DbParameter[] parameters)
        {
            return _db.ExecuteSqlQuery(procName, CommandType.StoredProcedure, parameters);
        }

        public int ExecuteFromSql(string sql, params DbParameter[] parameters)
        {
            return _db.ExecuteNonQuery(sql, CommandType.Text, parameters);

        }

        public int ExecuteFromProc(string procName, params DbParameter[] parameters)
        {
            return _db.ExecuteNonQuery(procName, CommandType.StoredProcedure, parameters);
        }

        public int Del(string id)
        {
            return _db.Database.ExecuteSqlRaw($"update Departments set IsChecks=1 where DepId in ({id})");
        }

        public int Upt(int id)
        {
            return _db.Database.ExecuteSqlRaw($"update Departments set Status=0 where DepId in ({id})");
        }
        public int Upt(UptDepartmentsDto model)
        {

            _db.Database.ExecuteSqlRaw($"update Departments set Name='{model.Name}' ,ParentId={model.ParentId},CascadeId='{model.CascadeId}',Status={model.Status} where DepId ={model.DepId}");
            return _db.SaveChanges();
        }
        #endregion
    }
}
